package com.xtayfjpk.zookeeper.test.master_workers.callback.recovery;


import java.util.List;

import org.apache.log4j.Logger;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.Code;

import com.xtayfjpk.zookeeper.test.master_workers.callback.BaseChildrenCallback;
import com.xtayfjpk.zookeeper.test.master_workers.recovery.RecoveredAssignments;
import com.xtayfjpk.zookeeper.test.master_workers.recovery.RecoveryCallback;

public class WorkerAssignmentsCallback extends BaseChildrenCallback {
	private final static Logger LOGGER = Logger.getLogger(WorkerAssignmentsCallback.class);
	private RecoveredAssignments assignments;
	
	public WorkerAssignmentsCallback(RecoveredAssignments recoveredAssignments) {
		this.assignments = recoveredAssignments;
	}


	@Override
	protected void connectionLossCaseAction(int rc, String path, Object ctx,
			List<String> children) {
		assignments.getWorkerAssignments(path);
	}
	
	/**
	 * children为分配了的任务
	 */
	@Override
	protected void okCaseAction(int rc, String path, Object ctx, List<String> children) {
		//获取工作者
		String worker = path.replaceFirst("/assign/", "");
		//如果该工作者为存活状态，则继续由该工作者执行任务
		if(assignments.getActiveWorkerList().contains(worker)) {
			assignments.getAssignmentList().addAll(children);
		} else {//如果该工作者已经死亡，则需要将该工作者的任务重新分配
			for(String task : children) {
				//如果待执行任务列表不包含当前任务则添加进待执行任务列表中
				if(!assignments.getTaskList().contains(task)) {
					assignments.getTaskList().add(task);
					//重新将未执行完成的任务添加回待执行任务列表
					assignments.getDataReassign(path, task);
				} else {//如果未执行完成的任务已经在待执行任务列表中，则直接删除未执行完成的任务
					assignments.deleteAssignment(path + "/" + task);
				}
				
				
			}
			
			/*
             * Delete the assignment parent. 
             */
			assignments.deleteAssignment(path);
		}
		
		assignments.getAssignedWorkerList().remove(worker);
		
		/*
         * Once we have checked all assignments,
         * it is time to check the status of tasks
         */
		if(assignments.getAssignedWorkerList().size()==0) {
			LOGGER.info("Getting statuses for recovery");
			assignments.getStatuses();
		}
	}
	
	@Override
	protected void noNodeCaseAction(int rc, String path, Object ctx,
			List<String> children) {
		LOGGER.info( "No such znode exists: " + path );
	}
	
	@Override
	protected void defaultCaseAction(int rc, String path, Object ctx, List<String> children) {
		LOGGER.error("getChildren failed",  KeeperException.create(Code.get(rc), path));
        assignments.getCb().recoveryComplete(RecoveryCallback.FAILED, null);
	}
}
